/*
 * HttpParser.h
 *
 */

#ifndef HTTPPARSER_H_
#define HTTPPARSER_H_

#include <exception>
#include "HttpHeader.h"
#include "HttpRequest.h"
#include "HttpResponse.h"

class ParserException : public std::exception {
	private:
		std::string msg;
		int errCode;
	public:
		ParserException(const std::string& msg, int code) throw();
		virtual ~ParserException() throw() {}
		const char* what() const throw() { return msg.c_str(); }
		int errno() const { return errCode; }
};

class HttpParser {
	private:
		HttpParser();
		virtual ~HttpParser();

		/** Parsea un Protocol Version de la forma: protocol/mayot.minor
		 * @param version Cadena de donde intentará tomar los datos
		 * @return Cadena con el nombre del protocolo
		 * @throw ParserException Si version está mal formado
		 */
		static std::string getProtocolName(const std::string& version);

		/** Parsea un Protocol Version de la forma: protocol/mayot.minor
		 * @param version Cadena de donde intentará tomar los datos
		 * @return Cadena con la mayor version
		 * @throw ParserException Si version está mal formado
		 */
		static std::string getMayorVersion(const std::string& version);
	public:
		/** Parsea un header de la forma: fieldName : field Value
		 * @param line Cadena donde intentará tomar los datos
		 * @return Un puntero a un HttpHeader cargado en el heap
		 * @throw ParserException Si el header esta mal formado
		 */
		static HttpHeader* parseHeader(const std::string& line);

		/** Parsea un request line de Http/1.0
		 * @param line Cadena donde intentará tomar los datos
		 * @return Un puntero a un HttpRequest cargado en el heap
		 * @throw ParserException Si la versión de protocolo del Request no
		 * es igual a la del host o el método Http no esta implementado.
		 */
		static HttpRequest* parseRequestLine(const std::string& line);

		/** Parsea los headers de salida de un CGI y carga un HttpResponse.
		 * @param response Response donde agregará los headers correspondientes
		 * @param data Stream de donde toma los datos a parsear
		 * @throw ParserException Si algún header falta o esta mal formado
		 */
		static void parseCgiHeaders(HttpResponse& response, std::stringstream& data);
};

#endif  /* HTTPPARSER_H_ */
